package its_models.tutor_model.tutor_help_util;

import java.util.Timer;
import java.util.TimerTask;
import model_controller.ControlLayer;
import sudoku_properties.SudokuGameInfoParam;

public class AutoHintsTimerHandler{

    public AutoHintsTimerHandler(ControlLayer inputController){
        timer=new Timer();
        Controller = inputController;
        timerTask = new  AutoHintsTimerHandlerTask(this, Controller);
        timer.schedule(timerTask, delay, WaitPeriod);

    }

    /********************************
     ** Start/Stop countup timer   **
     ********************************/
    public void reStartTimer(){
        timerTask.setTimerOff();
        timerTask.ResetTimer();
        timerTask.setTimerOn();
    }

    public void setTimerOff(){
        timerTask.setTimerOff();
    }

    public String getDisplayTime(){
        return timerTask.getStringTimeValue();
    }

    public int getTimeValueInSecond(){
        return timerTask.getTimerValue();
    }

    /* set time slot for providing hints */
    public void setTimeSlot(int time){
        timerTask.setTimeSlot(time);
    }

    public void setHintsLevel(int hintLevel){
        timerTask.setHintsLevel(hintLevel);
    }

    public void setAutoHitnsEnabled(boolean isEnabled){
        timerTask.setAutoHintssEnabled(isEnabled);
    }
    /* local variables */
    Timer timer;
    AutoHintsTimerHandlerTask timerTask;
    final int WaitPeriod=1000;
    final int delay=0;

    ControlLayer Controller;

}

class  AutoHintsTimerHandlerTask extends TimerTask {

    public  AutoHintsTimerHandlerTask(AutoHintsTimerHandler inputTimer, ControlLayer inputController){
        Controller = inputController;
        timer=inputTimer;
        timerValue=0;
        this.setTimerOff();
        timeSlot=0;
        hintsLevel=-1;
        isEnableAutoHints = true;
    }

    public void setTimeSlot(int inputTime){
        timeSlot=inputTime;
    }

    public void setHintsLevel(int inputHintsLevel){
        hintsLevel = inputHintsLevel;
    }

    public void setAutoHintssEnabled(boolean isEnabled){
        isEnableAutoHints = isEnabled;
    }

    public void run() {
        if(this.isTimerOn() && isEnableAutoHints ){
            this.TimerTick();
            if((hintsLevel+1)%HINTS_LEVEL.length ==0 ){
                /* if this is the first hints, wait for 4*timeSlot to give the first hints */
                if(this.getTimeValueInSecond()== timeSlot * HINTS_LEVEL.length){
                    hintsLevel++;
                    hintsLevel %= HINTS_LEVEL.length;
                    Controller.setTextLearnerStepsMsgBox(Controller.getHints(hintsLevel));
                    Controller.addNumHintsUsed(hintsLevel);
                    Controller.reStartAutoHintsTimer(hintsLevel);
                }
            }
            else if(this.getTimeValueInSecond()== timeSlot){
                hintsLevel++;
                hintsLevel %= HINTS_LEVEL.length;
                Controller.addNumHintsUsed(hintsLevel);
                Controller.setTextLearnerStepsMsgBox(Controller.getHints(hintsLevel));
                Controller.reStartAutoHintsTimer(hintsLevel);
            }
        }
    }

    /**********************************
     ** support function for run()   **
     **********************************/
    public String getStringTimeValue(){

        String TimeString="";

        final int IntTimeValue = this.getTimerValue();
        String StrHr = Integer.toString(IntTimeValue/ NumSecperHr) ;
        String StrMin = Integer.toString(( IntTimeValue % NumSecperHr) / NumSecperMin) ;
        String StrSec = Integer.toString(IntTimeValue % NumSecperMin) ;

        if (StrHr.length() == 1){
            StrHr = "0"+StrHr;
        }
        if (StrMin.length() == 1){
            StrMin = "0"+StrMin;
        }
        if (StrSec.length() == 1){
            StrSec = "0"+StrSec;
        }

        TimeString = StrHr + ":" + StrMin+ ":" + StrSec;

        return TimeString ;
    }

    public int getTimeValueInSecond(){
        return this.getTimerValue();
    }

    /***************************************
     ** check/set timer common function   **
     ***************************************/

    public synchronized boolean isTimerOn()
    {
        return isTimerOn ;
    }

    public synchronized void setTimerOn()
    {
        isTimerOn=true;
    }

    public synchronized void setTimerOff()
    {
        isTimerOn=false;
    }

    public synchronized int getTimerValue()
    {
        return timerValue ;
    }

    private synchronized void TimerTick()
    {
        ++timerValue;
    }

    public synchronized void ResetTimer()
    {
        timerValue=0;
    }

    /* local variables */
    private int timerValue;
    private boolean isTimerOn;
    private AutoHintsTimerHandler timer;
    private int timeSlot;
    private ControlLayer Controller;
    private int hintsLevel;
    private boolean isEnableAutoHints;

    /* constant variabls */
    /* SudokuGameInfoParam*/
    final String[] HINTS_LEVEL = SudokuGameInfoParam.getHintsLevel();

    /*****************************************************
     ** constant variable for calculating time string   **
     *****************************************************/
    final Integer NumSecperMin = 60;
    final Integer NumSecperHr = 3600;


}
